package yby

import (
	"fmt"
	"gitee.com/hongzhaomin/hzm-common-go/easycmd"
	"gitee.com/hongzhaomin/hzm-common-go/easyexcel"
	"gitee.com/hongzhaomin/hzm-common-go/streams"
	"github.com/xuri/excelize/v2"
)

const (
	season              = "季节"
	canSendStockTitle   = "可发库存"
	inTransitStockTitle = "采购在途"
	totalStockTitle     = "总库存"
)

var _ easycmd.Handler = (*FindStock)(nil)

type FindStock struct {
	SrcExcel string `json:"srcExcel,omitempty" argName:"s" usage:"需要查找库存的Excel文件"`
	DstExcel string `json:"dstExcel,omitempty" argName:"d" usage:"需要补充库存的Excel文件"`
}

func (my *FindStock) DoHandle(_ *easycmd.Command) {
	if my.SrcExcel == "" {
		fmt.Println("请输入需要查找库存的Excel文件, 例如: -s=a.xlsx")
		return
	}
	if my.DstExcel == "" {
		fmt.Println("请输入需要补充库存的Excel文件, 例如: -d=b.xlsx")
		return
	}
	my.doFindStock()
}

func (my *FindStock) doFindStock() {
	sStockBeans := easyexcel.ToBean[StockExcel]().ReadLocal(my.SrcExcel)
	sNo2BeanMap := my.toMapIdentity(sStockBeans)

	// 打开目标文件
	df, err := excelize.OpenFile(my.DstExcel)
	if err != nil {
		fmt.Println(fmt.Sprintf("读取excel文件[%s]失败: %v", my.DstExcel, err))
		return
	}
	defer df.Close()

	dRowsList, _ := df.GetRows(sheetName)
	titles := dRowsList[0]
	if streams.OfSlice(titles).NoneMatch(func(v string) bool { return no == v }) {
		fmt.Println(fmt.Sprintf("excel文件[%s]缺少表头信息: 找不到表头[%s]", my.DstExcel, no))
		return
	}

	noColIndex := 0
	for i, title := range titles {
		if no == title {
			noColIndex = i
			break
		}
	}
	startColNum := len(titles) + 1
	dColsList, _ := df.GetCols(sheetName)
	for dRowIndex, dNoVal := range dColsList[noColIndex] {
		var toAddRows []any
		dRowNum := dRowIndex + 1
		dStartCell, _ := excelize.CoordinatesToCellName(startColNum, dRowNum)
		if dNoVal == no {
			toAddRows = append(toAddRows, season, canSendStockTitle, inTransitStockTitle, totalStockTitle)
			if err = df.SetSheetRow(sheetName, dStartCell, &toAddRows); err != nil {
				fmt.Println(fmt.Sprintf("excel文件[%s]添加表头信息失败: %v", my.DstExcel, err))
				return
			}
			continue
		}
		bean, ok := sNo2BeanMap[dNoVal]
		if !ok {
			fmt.Println(fmt.Sprintf(">>> 未找到款号[%s]的库存信息", dNoVal))
			continue
		}
		toAddRows = append(toAddRows, bean.Season, bean.CanSendStock, bean.InTransitStock, bean.CanSendStock+bean.InTransitStock)
		if err = df.SetSheetRow(sheetName, dStartCell, &toAddRows); err != nil {
			fmt.Println(fmt.Sprintf(">>> 添加款号[%s]的库存信息失败: %v", dNoVal, err))
		}
	}

	if err = df.Save(); err != nil {
		fmt.Println(fmt.Sprintf("Excel文件[%s]保存失败: %v", my.DstExcel, err))
		return
	}
	fmt.Println(">>> 库存查找成功")
}

func (my *FindStock) toMapIdentity(ts []StockExcel) map[string]StockExcel {
	newMap := make(map[string]StockExcel, len(ts))
	for _, t := range ts {
		key := t.No
		old, ok := newMap[key]
		if !ok {
			newMap[key] = t
		} else {
			newMap[key] = StockExcel{
				No:             t.No,
				Season:         t.Season,
				CanSendStock:   t.CanSendStock + old.CanSendStock,
				InTransitStock: t.InTransitStock + old.InTransitStock,
			}
		}
	}
	return newMap
}

type StockExcel struct {
	No             string `json:"no,omitempty" title:"款号"`
	Season         string `json:"season,omitempty" title:"季节"`
	CanSendStock   int64  `json:"canSendStock,omitempty" title:"可发库存"`
	InTransitStock int64  `json:"inTransitStock,omitempty" title:"采购在途"`
}
